package com.sg.common.task;

import java.sql.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import org.apache.log4j.Logger;
import org.springframework.context.ApplicationContext;

import com.sg.common.properties.PropertyFileUtil;
import com.sg.common.utils.CollUtil;
import com.sg.common.utils.Constant;
import com.sg.common.utils.DateTimeUtils;

/**
 * now:16:27:00 task2 zhixing: 16:27 task2 zhixing over now:16:27:11 task2
 * zhixing: 16:27 task2 zhixing over now:16:27:22 task2 zhixing: 16:27
 * 
 * 主任务设定10s执行一次，分支任务执行11s后，导致主任务也延迟了1s。
 * 
 * 
 * now:16:31:31 task2 zhixing: 16:31 now:16:31:41 task2 zhixing: 16:31 task2
 * zhixing over now:16:31:51 task2 zhixing: 16:31 task2 zhixing over
 * now:16:32:01 task2 zhixing: 16:32 task2 zhixing over
 * 
 * 
 * 主任务中加入ExecutorService管理分支任务，即使分支任务执行11s后，主任务未发生延迟。
 * 
 * 
 * 任务管理类，管理任务的初始化、执行。
 * 
 * @author qianxiaowei
 * 
 */
public class TaskManager {

	private static Logger log = Logger.getLogger(TaskManager.class);

	public static Map<String, TimerTask> taskMap = new HashMap<String, TimerTask>();
	private final static ExecutorService executorService = Executors
			.newFixedThreadPool(5);
	private static final long PERIOD =  1000;// 间隔一秒，每秒钟执行，若后续扩展，需将执行时间随之扩展，如每秒执行，则tm中时间点需要精确到秒
	private static long count = 1;
	/**
	 * 该主任务 没一个PERIOD执行一次 每次执行有以下判断过程： 1、获取HH:mm， 2、获取 周几 HH:mm，
	 * 判断taskMap是否有以上时间点的对应的任务
	 */
	private static TimerTask MAIN_TASK = new TimerTask() {

		@Override
		public void run() {
			Date now = new Date(System.currentTimeMillis());
			String hhmm = DateTimeUtils.formatDate(now, "HH:mm");
//			if (hhmm.endsWith("00"))// 一小时输出一次
//				log.info("主任务执行 at:"
//						+ DateTimeUtils.formatDate(now, "yyyy-MM-dd HH:mm:ss"));
			// 此处可扩展

			if (taskMap != null) {

				// 1:每分钟执行的任务
				Set<String> keys = taskMap.keySet();
				for (String key : keys) {
					if (key.startsWith("second")) {
						String[] num = key.split("-");
						int  period=1;
						try {
							period=Integer.parseInt(num[1]);
						} catch (Exception e) {
							log.error("秒级任务周期转换失败，"+key);	
						}
						if (count % period == 0) {
							final TimerTask timerTask_min = taskMap.get(key);
							if (timerTask_min != null) {
								executorService.submit(new Runnable() {
									public void run() {
										timerTask_min.run();
									}
								});
							}
						}
						count++;
						//一天后计数回归为1
						if(count%86400==0)
						{
							count=1;
						}
					}
				}
				
//				// 1:每分钟执行的任务
//				Set<String> keys = taskMap.keySet();
//				for (String key : keys) {
//					if (key.startsWith("second")) {
//						String[] num = key.split("-");
//						if (count % Integer.parseInt(num[1]) == 0) {
//							final TimerTask timerTask_min = taskMap.get(key);
//							if (timerTask_min != null) {
//								executorService.submit(new Runnable() {
//									public void run() {
//										timerTask_min.run();
//									}
//								});
//							}
//						}
//					}
//				}

				// 1:每分钟执行的任务
				final TimerTask timerTask_min = taskMap.get("minute");
				if (timerTask_min != null) {
					executorService.submit(new Runnable() {
						public void run() {
							timerTask_min.run();
						}
					});
				}

				// 2：24小时制，获取HH:mm即可对应到Map中的任务
				final TimerTask timerTask = taskMap.get(hhmm);
				if (timerTask != null) {
					executorService.submit(new Runnable() {
						public void run() {
							timerTask.run();
						}
					});
				}

				// 3:每周的某个时间点发送，这里可以获取当前是周几，几点，来对应Map中的任务
				final TimerTask weekTimerTask = taskMap.get(DateTimeUtils
						.findDayOfWeek() + "w " + hhmm);
				if (weekTimerTask != null) {
					executorService.submit(new Runnable() {
						public void run() {
							weekTimerTask.run();
						}
					});
				}
			}
		}

	};

	/**
	 * 装满执行的任务队列 通过properties中的timer打头的常量
	 * 
	 * @param ctx
	 */
	public static void fillTm(ApplicationContext ctx) {
		Set<String> keySet = PropertyFileUtil.getKeys();
		for (String key : keySet) {
			if (key.startsWith("timer.")) {// 所有timer.开头的property
				try {
					String className = key.replaceFirst("timer.", "");
					AbsTimerTask tt = (AbsTimerTask) Class.forName(className)
							.newInstance();
					tt.setCtx(ctx);
					taskMap.put(PropertyFileUtil.get(key), tt.createTimerTask());
					log.info("put " + PropertyFileUtil.get(key) + ", "
							+ tt.toString() + " into TaskManager.tm");
				} catch (Exception e) {
					e.printStackTrace();
					log.error(e.getMessage());
				}
			}
		}
	}

	/**
	 * 执行主任务
	 */
	public static void exec() {
		new Timer().scheduleAtFixedRate(MAIN_TASK,
				new Date(System.currentTimeMillis()), PERIOD);
	}
}
